import React, { useState, useEffect, useRef } from 'react';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';

import {
  Box,
  Button,
  Typography,
  FormControl,
  FormLabel,
  RadioGroup,
  FormControlLabel,
  Radio,
  Grid,
  Paper,
  Stack,
  Divider
} from '@mui/material';

export default function ControlPanel() {
  const [log, setLog] = useState([]);
  const [wsConnected, setWsConnected] = useState(false);
  const [xySpeed, setXySpeed] = useState(40); // 默认速度40%
  const [zSpeed, setZSpeed] = useState(0);
  const [duration, setDuration] = useState('infinite');
  const [beepDuration, setBeepDuration] = useState('infinite');
  
  const [alertLogs, setAlertLogs] = useState([]); // 检测日志
  const [alertDialog, setAlertDialog] = useState({ open: false, img: '', type: '', time: '' });
  const wsRef = useRef(null);
  const lastCommandTime = useRef(0); // 跟踪上次指令发送时间

  // 将百分比速度(-100%~100%)转换为协议要求的十六进制值
  const speedToHex = (speedPercent) => {
    const speed = Math.round(speedPercent);
    if (speed >= 0) {
      return Math.min(Math.round((speed / 100) * 0x64), 0x64)
        .toString(16)
        .padStart(2, '0')
        .toUpperCase();
    } else {
      const absSpeed = Math.min(Math.abs(speed), 100);
      const hexValue = 256 - Math.round((absSpeed / 100) * 0x64);
      return hexValue.toString(16).padStart(2, '0').toUpperCase();
    }
  };

  // 添加日志
  const addLog = (msg, type = 'info') => {
    const timestamp = new Date().toISOString().slice(-13, -1);
    setLog((prev) => [...prev, `[${timestamp}] ${msg}`].slice(-100));
    if (type === 'error') toast.error(msg);
    else if (type === 'success') toast.success(msg);
    else toast(msg);
  };

  // 建立 WebSocket 连接
  const connectWs = () => {
    if (wsRef.current) {
      wsRef.current.close();
      wsRef.current = null;
      setWsConnected(false);
    }
    const ws = new WebSocket('ws://localhost:8080');
    ws.onopen = () => {
      setWsConnected(true);
      addLog('[WebSocket] 连接成功', 'success');
    };
    ws.onmessage = (e) => addLog(`[小车反馈] ${e.data}`);
    ws.onerror = () => addLog('[WebSocket] 发生错误', 'error');
    ws.onclose = () => {
      setWsConnected(false);
      addLog('[WebSocket] 连接关闭', 'info');
    };
    wsRef.current = ws;
  };

  // 初始化设备
  const handleInit = async () => {
    try {
      const res = await fetch('http://localhost:8080/init');
      const text = await res.text();
      addLog(`[Init] ${text}`, 'success');
    } catch (err) {
      addLog(`[Init错误] ${err.message}`, 'error');
    }
  };

  // 计算校验位
  const calcChecksum = (hexStr) => {
    let sum = 0;
    for (let i = 0; i < hexStr.length; i += 2) {
      sum += parseInt(hexStr.substr(i, 2), 16);
    }
    return (sum % 256).toString(16).padStart(2, '0').toUpperCase();
  };

  // 构造方向指令
  const makeDirectionCommand = (carType, directionCode) => {
    const func = '15';
    const len = '04';
    const dirHex = directionCode.toString(16).padStart(2, '0').toUpperCase();
    const body = carType.toUpperCase() + func + len + dirHex;
    const checksum = calcChecksum(body);
    const cmd = `$${body}${checksum}#`;
    if (cmd.length !== 12) {
      addLog(`[警告] 方向指令长度异常: ${cmd} (长度: ${cmd.length})`, 'error');
    }
    return cmd;
  };

  // 构造简单功能指令
  const makeSimpleCommand = (carType, funcCode) => {
    const len = '02';
    const func = funcCode.toUpperCase();
    const body = carType.toUpperCase() + func + len;
    const checksum = calcChecksum(body);
    const cmd = `$${body}${checksum}#`;
    if (cmd.length !== 8) {
      addLog(`[警告] 功能指令长度异常: ${cmd} (长度: ${cmd.length})`, 'error');
    }
    return cmd;
  };

  // 构造速度指令
  const makeSpeedCommand = (carType, xySpeed, zSpeed) => {
    const func = '16';
    const xyHex = speedToHex(xySpeed);
    const zHex = speedToHex(zSpeed);
    const bodyWithoutLen = func + xyHex + zHex;
    const len = bodyWithoutLen.length.toString(16).padStart(2, '0').toUpperCase();
    const body = carType.toUpperCase() + func + len + xyHex + zHex;
    const checksum = calcChecksum(body);
    const cmd = `$${body}${checksum}#`;
    if (cmd.length !== 14) {
      addLog(`[警告] 速度指令长度异常: ${cmd} (长度: ${cmd.length})`, 'error');
    }
    return cmd;
  };

  const makeBeepCommand = (carType, delayMs) => {
  const func = '13';
  const len = '06';
  const state = '01';
  let delayByte;

  if (delayMs === 'infinite') {
    delayByte = 'FF';
  } else {
    const ms = Number(delayMs);
    const delayVal = Math.min(Math.round(ms / 10), 254);
    delayByte = delayVal.toString(16).padStart(2, '0').toUpperCase();
  }

  const body = carType + func + len + state + delayByte;
  const checksum = calcChecksum(body);
  const cmd = `$${body}${checksum}#`;

  // if (cmd.length !== 14) {
  //   addLog(`[警告] 蜂鸣器指令长度异常: ${cmd} (长度: ${cmd.length})`, 'error');
  // }

  return cmd;
};

  // 发送指令
  const sendCommand = (cmd) => {
    const now = Date.now();
    const MIN_INTERVAL = 100;
    if (!wsRef.current || !wsConnected) {
      addLog('[错误] WebSocket未连接', 'error');
      return;
    }
    if (now - lastCommandTime.current < MIN_INTERVAL) {
      addLog(`[警告] 指令发送过密，已忽略: ${cmd}`, 'error');
      return;
    }
    wsRef.current.send(cmd);
    addLog(`[发送] ${cmd}`, 'info');
    lastCommandTime.current = now;
  };

  // 自动连接WebSocket
  useEffect(() => {
    connectWs();
    // 获取检测日志
    fetchAlerts();
    const interval = setInterval(fetchAlerts, 5000); // 每5秒刷新一次
    return () => {
      if (wsRef.current) wsRef.current.close();
      clearInterval(interval);
    };
  }, []);

  // 获取检测日志
  const fetchAlerts = async () => {
    try {
      const res = await fetch('http://localhost:8088/api/alerts');
      if (!res.ok) return;
      const data = await res.json();
      setAlertLogs(Array.isArray(data) ? data : []);
    } catch (e) {
      // 忽略错误
    }
  };

  // 【核心修改】速度选择变化时直接发送速度指令
  const handleSpeedChange = (e) => {
    const newSpeed = Number(e.target.value);
    setXySpeed(newSpeed);
    // 生成并发送速度指令
    const speedCmd = makeSpeedCommand('01', newSpeed, zSpeed);
    sendCommand(speedCmd);
  };

  // 指令按钮组件
  const CommandButton = ({ label, commandBuilder }) => (
    <Button
      variant="contained"
      sx={{
        bgcolor: '#ff69b4',
        color: '#fff',
        '&:hover': { bgcolor: '#ff85c1' },
        textTransform: 'none',
        fontWeight: 'bold',
        borderRadius: 2
      }}
      onClick={() => {
        const cmd = commandBuilder();
        if (cmd) sendCommand(cmd);
      }}
    >
      {label}
    </Button>
  );

  return (
    <Paper elevation={3} sx={{ p: 3, bgcolor: '#fdf6f9', borderRadius: 4, minHeight:760, maxHeight: 1000, height: 'auto' }}>
      <ToastContainer position="top-right" />

      <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 2 }}>
        <Typography variant="h5" gutterBottom sx={{ fontWeight: 'bold', color: '#ff69b4', mb: 0 }}>
          智能小车控制面板
        </Typography>
        <Box>
          <Button 
            onClick={handleInit} 
            variant="outlined" 
            color="primary"
            sx={{ mr: 1 }}
          >
            手动初始化设备
          </Button>
          <Button 
            onClick={connectWs} 
            variant="outlined"
            color={wsConnected ? "success" : "secondary"}
          >
            {wsConnected ? '断开WebSocket连接' : '连接WebSocket'}
          </Button>
        </Box>
      </Box>

      <Grid container spacing={3}>
        <Grid item xs={6}>
          <FormControl component="fieldset">
            <FormLabel sx={{ color: '#ff69b4', fontWeight: 'bold' }}>🚀 速度选择</FormLabel>
            {/* 【核心修改】绑定速度变化事件 */}
            <RadioGroup row value={xySpeed} onChange={handleSpeedChange}>
              {[40, 70, 100].map((val) => (
                <FormControlLabel
                  key={val}
                  value={val}
                  control={<Radio sx={{ color: '#ff69b4', '&.Mui-checked': { color: '#ff69b4' } }} />}
                  label={`${val}%`}
                />
              ))}
            </RadioGroup>
          </FormControl>
        </Grid>

        <Grid item xs={6}>
          <FormControl component="fieldset">
            <FormLabel sx={{ color: '#ff69b4', fontWeight: 'bold' }}>⏱️ 持续时间</FormLabel>
            <RadioGroup row value={duration} onChange={(e) => setDuration(e.target.value)}>
              {[
                { label: '持续', value: 'infinite' },
                { label: '0.5 秒', value: 500 },
                { label: '1.0 秒', value: 1000 },
                { label: '5.0 秒', value: 5000 },
              ].map(({ label, value }) => (
                <FormControlLabel
                  key={value}
                  value={value.toString()}
                  control={<Radio sx={{ color: '#a972ff', '&.Mui-checked': { color: '#a972ff' } }} />}
                  label={label}
                />
              ))}
            </RadioGroup>
          </FormControl>
        </Grid>
      </Grid>

      <Divider sx={{ my: 2 }} />

      <Typography variant="h6" sx={{ color: '#ff69b4', fontWeight: 'bold' }}>🎮 方向控制</Typography>
      <Stack direction="row" spacing={2} flexWrap="wrap" mb={2}>
        {[
          { label: '停止', code: 0 },
          { label: '向前', code: 1 },
          { label: '向后', code: 2 },
          { label: '向左', code: 3 },
          { label: '向右', code: 4 },
          { label: '左旋', code: 5 },
          { label: '右旋', code: 6 },
          { label: '停车', code: 7 },
        ].map(({ label, code }) => (
          <CommandButton
            key={code}
            label={label}
            commandBuilder={() => {
              const directionCmd = makeDirectionCommand('01', code);
              
              // 【核心修改】移除速度指令相关逻辑，仅发送方向指令
              sendCommand(directionCmd);
              
              // 自动停止逻辑保留
              if (duration !== 'infinite' && code !== 0) {
                setTimeout(() => {
                  const stopCmd = makeDirectionCommand('01', 0);
                  sendCommand(stopCmd);
                  addLog(`🛑 ${duration}ms 后已自动停止`, 'success');
                }, Number(duration));
              }
              return '';
            }}
          />
        ))}
      </Stack>

      <Typography variant="h6" sx={{ color: '#ff69b4', fontWeight: 'bold' }}>⚙️ 功能控制</Typography>
      <Stack direction="row" spacing={2} flexWrap="wrap" mb={2}>
        <CommandButton label="📷 保存图片" commandBuilder={() => makeSimpleCommand('01', '60')} />
        <CommandButton label="🎥 开始录像" commandBuilder={() => makeSimpleCommand('01', '61')} />
        <CommandButton label="🛑 停止录像" commandBuilder={() => makeSimpleCommand('01', '62')} />
        <CommandButton label="🚗 启动巡线" commandBuilder={() => makeSimpleCommand('01', '63')} />
        <CommandButton label="⛔ 停止巡线" commandBuilder={() => makeSimpleCommand('01', '64')} />
        <CommandButton label="🧠 启动雷达避障" commandBuilder={() => { addLog('🧠 发送启动雷达避障指令...');
        return makeSimpleCommand('01', '65');
          }} 
        />
      </Stack>
      <Divider sx={{ my: 2 }} />
      <Typography variant="h6" sx={{ color: '#ff69b4', fontWeight: 'bold' }}>
        🔊 蜂鸣器控制
      </Typography>
      <Grid container spacing={2} alignItems="center" sx={{ width: '100%', mt: 1 }}>
        <Grid item xs={8} md={9} lg={10}>
          <FormControl component="fieldset" sx={{ width: '100%' }}>
            <FormLabel sx={{ color: '#ff69b4', fontWeight: 'bold' }}>鸣笛时长</FormLabel>
            <RadioGroup
              row
              value={beepDuration}
              onChange={(e) => setBeepDuration(e.target.value)}
              sx={{ alignItems: 'center' }}
            >
              {[{ label: '持续', value: 'infinite' }, { label: '0.5 秒', value: 500 }, { label: '1.0 秒', value: 1000 }, { label: '5.0 秒', value: 5000 }].map(({ label, value }) => (
                <FormControlLabel
                  key={value}
                  value={value.toString()}
                  control={<Radio sx={{ color: '#ff69b4', '&.Mui-checked': { color: '#ff69b4' } }} />}
                  label={label}
                  sx={{ mr: 2 }}
                />
              ))}
            </RadioGroup>
          </FormControl>
        </Grid>
        <Grid item xs={4} md={3} lg={2} sx={{ display: 'flex', alignItems: 'center', height: '100%' }}>
          <Button
            variant="contained"
            onClick={() => {
              const beepCmd = makeBeepCommand('01', beepDuration);
              sendCommand(beepCmd);
            }}
            sx={{
              bgcolor: '#ff69b4',
              color: '#fff',
              '&:hover': { bgcolor: '#ff85c1' },
              textTransform: 'none',
              fontWeight: 'bold',
              borderRadius: 2,
              px: 3,
              py: 1.2,
              minWidth: 100
            }}
          >
            🚨 发送蜂鸣器指令
          </Button>
        </Grid>
      </Grid>
      <Box sx={{ mt: 'auto', pt: 2 }}>
        <Typography variant="h6" sx={{ color: '#ff69b4', fontWeight: 'bold' }}>📝 操作日志</Typography>
        <Box
          sx={{
            height: 100,
            overflowY: 'auto',
            bgcolor: '#fff0f5',
            borderRadius: 2,
            p: 2,
            mt: 1,
            fontFamily: 'monospace',
            fontSize: '0.95rem',
            border: '1px solid #ffd6e8'
          }}
        >
          {log.length === 0 && <div style={{ color: '#e0a6c6' }}>暂无操作日志</div>}
          {log.map((line, idx) => (
            <div
              key={idx}
              style={{
                color: line.includes('错误') ? '#ff4d6d' :
                  line.includes('成功') ? '#ff69b4' :
                    line.includes('发送') ? '#a972ff' : '#b4004e'
              }}
            >
              {line}
            </div>
          ))}
        </Box>

        <Typography variant="h6" sx={{ color: '#ff69b4', fontWeight: 'bold', mt: 3 }}>🕵️ 检测日志</Typography>
        <Box
          sx={{
            height: 130,
            overflowY: 'auto',
            bgcolor: '#fff0f5',
            borderRadius: 2,
            p: 2,
            mt: 1,
            fontFamily: 'monospace',
            fontSize: '0.95rem',
            border: '1px solid #ffd6e8'
          }}
        >
          {(!alertLogs || alertLogs.length === 0) && <div style={{ color: '#e0a6c6' }}>暂无检测日志</div>}
          {alertLogs && alertLogs.length > 0 && alertLogs.map((item, idx) => {
            if (!item) return null;
            const date = new Date(item.timestamp * 1000);
            const timeStr = date.toLocaleString('zh-CN', { hour12: false });
            let typeText = '';
            if (item.type === 'fire') typeText = '🔥 火焰';
            else if (item.type === 'falling') typeText = '🤸 跌倒';
            else if (item.type === 'fighting') typeText = '🥊 打架';
            else typeText = item.type;
            return (
              <div
                key={idx}
                style={{
                  color: '#ff69b4',
                  cursor: 'pointer',
                  marginBottom: 8,
                  background: '#ffe4f0',
                  borderRadius: 6,
                  padding: '6px 10px',
                  transition: 'background 0.2s',
                  border: '1px solid #ffd6e8',
                  boxShadow: '0 1px 2px #eee',
                  display: 'flex',
                  alignItems: 'center',
                }}
                onClick={() => setAlertDialog({ open: true, img: item.image_base64, type: typeText, time: timeStr })}
                title="点击查看图片"
              >
                <span style={{ fontWeight: 'bold', color: item.type === 'fire' ? '#ff4d6d' : '#b4004e', minWidth: 60 }}>{typeText}</span>
                <span style={{ marginLeft: 18, color: '#b4004e', fontSize: 14 }}>{timeStr}</span>
              </div>
            );
          })}
        </Box>
      </Box>
      {/* 检测图片弹窗 */}
      {alertDialog.open && (
        <Box
          sx={{
            position: 'fixed',
            top: 0,
            left: 0,
            width: '100vw',
            height: '100vh',
            zIndex: 9999,
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            // 移除背景色
          }}
          onClick={() => setAlertDialog({ open: false, img: '', type: '', time: '' })}
        >
          <Box
            sx={{
              bgcolor: '#fff0f5',
              borderRadius: 3,
              p: 3,
              minWidth: 320,
              maxWidth: '90vw',
              maxHeight: '90vh',
              boxShadow: 8,
              display: 'flex',
              flexDirection: 'column',
              alignItems: 'center',
              border: '2px solid #ff69b4',
            }}
            onClick={e => e.stopPropagation()}
          >
            <Typography variant="h6" sx={{ mb: 1, color: '#ff69b4' }}>{alertDialog.type} 检测图片</Typography>
            <Typography variant="body2" sx={{ mb: 2, color: '#b4004e' }}>{alertDialog.time}</Typography>
            {/* 直接显示本地图片（file:// 协议，仅本地环境可用） */}
            {alertDialog.img && (
              <img
                src={(() => {
                  // 只取 public 目录下的文件名部分
                  const imgPath = alertDialog.img.replace(/\\/g, '/');
                  const fileName = imgPath.split('/').pop();
                  return fileName ? `/${fileName}` : '';
                })()}
                alt="检测图片"
                style={{ maxWidth: 500, maxHeight: 400, borderRadius: 8, border: '2px solid #ff69b4', background: '#fff' }}
              />
            )}
            <Button sx={{ mt: 2, color: '#ff69b4', borderColor: '#ff69b4' }} variant="outlined" onClick={() => setAlertDialog({ open: false, img: '', type: '', time: '' })}>关闭</Button>
          </Box>
        </Box>
      )}
    </Paper>
  );
}
